import test_framework.test.unit.TestCase;
import mx.utils.Delegate;

import gugga.sequence.TaskManager;
import gugga.sequence.FictiveTask;
import gugga.sequence.ExecuteAsyncMethodTask;
import gugga.common.EventDescriptor;

import guggaLibTests.support.TaskExecutionEvaluator;
import guggaLibTests.support.PauseResumeMethodsSequence;

import gugga.common.ITask;
import gugga.sequence.PreconditionsTask;
import gugga.sequence.PreconditionsManager;
import gugga.utils.DebugUtils;
import mx.events.EventDispatcher;
import gugga.debug.Debugger;

import gugga.sequence.SingleExecutionTask;
import test_framework.test.unit.info.AssertFalseInfo;
import gugga.debug.Assertion;
import gugga.sequence.WaitingTask;

/**
 * @author stefan
 */
class guggaLibTests.WaitingTaskTest extends TestCase 
{
	private var delayInterval:Number = 1000;
	private var mTask : ITask;
	
	public function WaitingTaskTest ()
	{
		super();

		this.delayInterval = 1000;
	}
	
	public function testConstructor ()
	{
		var task : ITask = new WaitingTask(300);
		
		assertInstanceOf(
			"the constructor should return an instance of the WaitingTask class",
			task,
			WaitingTask
		);
	}
	
	public function testStartAndCompletion ()
	{
		var evaluator : TaskExecutionEvaluator = new TaskExecutionEvaluator(this);
		
		var actualTask : ITask = new FictiveTask();
		var task1 : ITask = new WaitingTask(1.5);
		
		mTask = task1;
		
		task1.addEventListener("start", Delegate.create(evaluator, evaluator.onTaskStarted));
		task1.addEventListener("completed", Delegate.create(evaluator, evaluator.onTaskCompleted));
		
		assertFalse(
			"the task should not be running before start",
			task1.isRunning()
		);
		
		var obj = this;
		
		var firstBlock = function ()
		{
			evaluator.registerRequiredTaskStatus( {task: task1, event: "start"} );		
		
			task1.start();			
		};
		
		var secondBlock = function ()
		{
			evaluator.evaluateTaskExecution();
			evaluator.assertTaskStatusRegisterEqualsRequiredTaskStatusRegister("the task should not complete before the waiting interval");
			
			obj.assertIsRunning();

			evaluator.registerRequiredTaskStatus( {task: task1, event: "completed"} );
		};
		
		var thirdBlock = function ()
		{
			evaluator.evaluateTaskExecution();
			evaluator.assertTaskStatusRegisterEqualsRequiredTaskStatusRegister("the task should complete after the waiting interval");
			
			obj.assertNotRunning();
		};
		
		var pauseAndResumer : PauseResumeMethodsSequence = new PauseResumeMethodsSequence(
			this,
			1000,
			[firstBlock,
			secondBlock,
			thirdBlock]
		);
		pauseAndResumer.start();
	}
	
	private function assertIsRunning ()
	{
		assertTrue(
			"the task should be running",
			mTask.isRunning()			
		);
	}
	
	private function assertNotRunning()
	{
		assertFalse(
			"the task should not be running after completion",
			mTask.isRunning()			
		);
	}
	
	private function emptyMethod()
	{
		//
	}
}